from typing import List
import jsonfield
from django.core.validators import MinValueValidator
from django.db import models
import uuid

class Deployment(models.Model):
    Env_CHOICES = (
        ('Cloud', 'Cloud'),
        ('Edge', 'Edge'),)
    id =  models.AutoField(primary_key=True)
    deployment_name = models.CharField(max_length=30,unique=True)
    namespace = models.CharField(max_length=30,default='Default')
    deployment_type = models.CharField(max_length=16,choices=Env_CHOICES)
    replica = models.IntegerField()
    full_map = jsonfield.JSONField()

    def __str__(self):
        return self.deployment_name

class Container(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=16)
    image = models.CharField(max_length=30)
    deployment = models.ForeignKey(Deployment, related_name='pod',on_delete=models.CASCADE, blank=True, null=True)

    def __str__(self):
        return self.name

class PodPort(models.Model):
    id = models.AutoField(primary_key=True)
    containerPort = models.IntegerField(null=True)
    hostPort = models.IntegerField(null=True,blank=True)
    pod = models.ForeignKey(Container, related_name='ports', on_delete=models.CASCADE, blank=True, null=True)

    def __str__(self):
        return self.containerPort

class K8sJob(models.Model):
    TYPE_CHOICES = (
        ('cpu', 'cpu'),
        ('gpu', 'gpu'),
        ('tpu', 'tpu'),
    )
    AlGORITHM_CHOICES = (
        (1, 'Data Volume Filtering Algorithm'),
        (2, 'Node Percentage Filtering Algorithm'),
    )
    id = models.AutoField(primary_key=True)
    namespace = models.CharField(max_length=30,null=True,blank=True)
    uuid = models.UUIDField(default=uuid.uuid4, editable=False)
    name = models.CharField(max_length=32)
    image = models.CharField(max_length=128)
    require_data = models.IntegerField(default=0,null=True,blank=True)
    node_percent = models.FloatField(default=0,null=True,blank=True)
    is_parallel = models.BooleanField(default=0,null=True,blank=True)
    weight = models.FloatField()
    type = models.CharField(choices=TYPE_CHOICES,max_length=16)
    pu = models.IntegerField(default=0)
    ram = models.IntegerField(default=0)
    disk = models.IntegerField(default=0)
    algorithm = models.IntegerField(choices=AlGORITHM_CHOICES,default=1)

class DockerEnv(models.Model):
    id = models.AutoField(primary_key=True)
    key = models.CharField(max_length=32)
    value = models.CharField(max_length=32)
    job = models.ForeignKey(K8sJob, default=None, related_name='envs', on_delete=models.CASCADE, blank=True, null=True)

class TaskRecord(models.Model):
    TYPE_CHOICES = (
        (0, 'Learning'),
        (1, 'Validation')
    )
    id = models.AutoField(primary_key=True)
    hostname = models.CharField(max_length=16,null=True,blank=True)
    task_name = models.CharField(max_length=128,unique=True,null=True,blank=True)
    cpu_x = models.FloatField(null=True,blank=True)
    cpu_y = models.IntegerField(null=True,blank=True)
    data_x = models.FloatField(null=True,blank=True)
    data_y = models.IntegerField(null=True,blank=True)
    disk =  models.IntegerField(null=True,blank=True)
    ram = models.IntegerField(null=True,blank=True)
    score = models.FloatField(null=True,blank=True)
    status = models.IntegerField(null=True,blank=True)
    output = models.CharField(max_length=100,null=True,blank=True)
    role = models.IntegerField(choices=TYPE_CHOICES,default=0) #0. learning 1.validation
    job = models.ForeignKey(K8sJob, default=None, related_name='jobarray', on_delete=models.CASCADE, blank=True, null=True)

class Container_Vo():
    def __init__(self, name, image, ports: List[PodPort]):
        self.name = name
        self.image = image
        self.ports = ports or []

class Condition_Vo():
    def __init__(self, last_transition_time, last_update_time, message, reason, status, type):
        self.last_transition_time = last_transition_time
        self.last_update_time = last_update_time
        self.message = message
        self.reason = reason
        self.status = status
        self.type = type

class Deployment_Vo():
    def __init__(self, pod: List[Container],deployment_name,namespace,deployment_type,replica: int,full_map,available_replicas,collision_count,
                 conditions: List[Condition_Vo],observed_generation,ready_replicas,updated_replicas,labels,run):
        self.deployment_name = deployment_name
        self.namespace = namespace
        self.deployment_type = deployment_type
        self.replica = replica
        self.full_map = full_map
        self.available_replicas = available_replicas
        self.collision_count = collision_count
        self.conditions= conditions
        self.observed_generation = observed_generation
        self.ready_replicas = ready_replicas
        self.updated_replicas = updated_replicas
        self.pod = pod
        self.run = run
        self.labels = labels



